package com.example.loop.configuration;

import com.example.loop.entity.Role;
import com.example.loop.entity.User;
import com.example.loop.service.PermissionService;
import com.example.loop.service.RoleService;
import com.example.loop.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author Liaorun
 */
@Slf4j
public class UserRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private PermissionService permissionService;

    /**
     * 用户授权的方法，当用户访问需要权限的界面，就会调用这个方法检查是否有权限
     *
     * @param principalCollection
     * @return 用户所有的角色和权限信息
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.info("用户授权");

        User user = (User) principalCollection.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

        // 查询用户的所有角色
        List<Role> roleList = roleService.findRoleByUserId(user.getId());
        // id 集合，给shiro授权
        Set<String> roleSet = new HashSet<>();
        // id 数组，用于查询权限
        List<Integer> roleIds = new ArrayList<>();
        for (Role role : roleList) {
            roleSet.add(role.getRole());
            roleIds.add(role.getId());
        }
        // 放入角色信息
        authorizationInfo.setRoles(roleSet);

        // 查询用户的所有权限
        List<String> permissionList = permissionService.findByRoleId(roleIds);

        // 放入权限信息
        authorizationInfo.setStringPermissions(new HashSet<>(permissionList));

        return authorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        log.info("开始认证");


        // 获取当前的用户
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;

        // 数据库检查用户名存在与否
        User user = userService.findByAccount(token.getUsername());
        if (user == null) {
            return null;
        }



        // 检查用户密码是否正确
        // 1 用户对象； 2 正确的密码； 3 不知道；
        return new SimpleAuthenticationInfo(user, user.getPassword(), getName());

    }
}
